package com.onpositive.wiki3.db;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import com.onpositive.compactdata.FuzzyStringMap;
import com.onpositive.nlp.inflector.StringLevenshteinDisstanceComputer;
import com.onpositive.wiki2.whole.model.ITemplateAccess;
import com.onpositive.wiki3.db.catmodel.CompactCats;
import com.onpositive.wiki3.db.catmodel.CompactCats.DS;
import com.onpositive.wiki3.db.impl.CountingVocabalary;
import com.onpositive.wiki3.db.impl.CountingVocabalary.Pair;

public class SimpleValueModel implements IValueModel {

	public SimpleValueModel(IWikiDB db, CompactCats cats) {
		super();
		this.db = db;
		this.cats = cats;
	}

	int total;
	int totalTemplates;

	public SimpleValueModel(IWikiDB db2, CompactCats store,
			CountingVocabalary object) {
		this.db = db2;
		this.cats = store;
		buildTemplateModel(object);
		this.temlates = db2.getTemlates();
	}

	protected void buildTemplateModel(CountingVocabalary object) {
		ITemplateAccess temlates = db.getTemlates();
		ITitleMapper titleMapper = db.getTitleMapper();
		CountingVocabalary vs = new CountingVocabalary();
		for (Pair mString : object.all()) {
			knownValues.add(FuzzyStringMap.transform(mString.s), mString.i);
			total += mString.i;
			int[] allFuzzyMatches = titleMapper.getAllFuzzyMatches(mString.s);
			for (int q : allFuzzyMatches) {
				String[] templates2 = temlates.getTemplates(q);
				if (templates2.length > 0) {
					totalTemplates += mString.i;
				}
				for (String c : templates2) {
					templates.add(c, mString.i);
				}
				int[] parents = cats.getParents(q);
				for (int qa : parents) {
					String title = titleMapper.getTitle(qa);
					if (title.startsWith("use_dmy_dates")) {
						continue;
					}
					if (title.contains("redirects")) {
						continue;
					}
					if (title.contains("_pages")) {
						continue;
					}
					if (title.contains("_disputes")) {
						continue;
					}
					if (title.contains("articles")) {
						continue;
					}
					vs.add(title, mString.i);
				}
				// System.out.println(Arrays.toString(templates2));
			}
		}
		CountingVocabalary v = new CountingVocabalary();
		for (Pair p : this.templates.all()) {
			if (p.i * 10 > total) {
				v.add(p.s, p.i);
			}
		}
		CountingVocabalary cats = new CountingVocabalary();
		for (Pair p : vs.all()) {
			if (p.i * 10 > total) {
				cats.add(p.s, p.i);
			}
		}
		this.directCats = cats;
		this.templates = v;

	}

	protected CompactCats cats;
	ITemplateAccess temlates;

	protected CountingVocabalary templates = new CountingVocabalary();

	protected CountingVocabalary directCats = new CountingVocabalary();

	protected final CountingVocabalary knownValues = new CountingVocabalary();

	protected final Set<DS> knownCats = new HashSet<CompactCats.DS>();

	protected final IWikiDB db;

	protected HashMap<String, Double> vs = new HashMap<String, Double>();

	@Override
	public double weight(String value) {
		if (vs.containsKey(value)) {
			return vs.get(value);
		}
		double internalW = internalW(value);
		vs.put(value, internalW);
		return internalW;
	}

	protected double internalW(String value) {
		
		if (value.length() <= 3) {
			return 0.1;
		}
		String transform = FuzzyStringMap.transform(value);
		if (knownValues.get(transform) != null) {
			if (value.equals("engine")){
				System.out.println("A");
			}
			return 1.0;
		}

		for (String q : knownValues.values()) {
			if (StringLevenshteinDisstanceComputer.computeSmartDisstance(q, value) < 2
					&& Math.abs(value.length() - q.length()) < 3) {
				if (value.equals("engine")){
					System.out.println("A");
				}		
				return 0.8;
			}
		}
		int[] allFuzzyMatches = db.getTitleMapper().getAllFuzzyMatches(value);
		for (int q : allFuzzyMatches) {

			ITitleMapper titleMapper = db.getTitleMapper();
			String title = titleMapper.getTitle(q);
			transform = FuzzyStringMap.transform(title);
			if (knownValues.get(transform) != null) {
				return 1.0;
			}

			for (String qr : knownValues.values()) {
				if (StringLevenshteinDisstanceComputer.computeSmartDisstance(qr,
						value) < 2
						&& Math.abs(value.length() - qr.length()) < 3) {
					if (value.equals("engine")){
						System.out.println("A");
					}
					return 0.8;
				}
			}

			String[] templates2 = temlates.getTemplates(q);
			for (String s : templates2) {
				if (this.templates.get(s) != null) {
					return 0.1;
				}
			}
		}
		return 0;
	}

	public String toString() {
		StringBuilder bld = new StringBuilder();
		for (Pair q : templates.all()) {
			bld.append(q.toString());
			bld.append(';');
		}
		for (Pair q : directCats.all()) {
			bld.append(q.toString());
			bld.append(';');
		}
		return totalTemplates + "/" + total + ":" + bld.toString();
	}

	public int size() {
		return toString().indexOf(';');
	}

}